#include <iostream>
#include <vector>
#include <chrono>
#include <random>
#include <iomanip>

class Matrix {
private:
    std::vector<std::vector<double>> data;
    int rows;
    int cols;

public:
    // 构造函数
    Matrix(int r, int c) : rows(r), cols(c) {
        data.resize(rows, std::vector<double>(cols, 0.0));
    }

    // 随机初始化矩阵
    void randomInitialize() {
        std::random_device rd;
        std::mt19937 gen(rd());
        std::uniform_real_distribution<> dis(0.0, 100.0);

        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < cols; ++j) {
                data[i][j] = dis(gen);
            }
        }
    }

    // 行优先访问（横向遍历）
    double rowMajorAccess() {
        double sum = 0.0;
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < cols; ++j) {
                sum += data[i][j];  // 连续访问同一行的元素
            }
        }
        return sum;
    }

    // 列优先访问（纵向遍历）
    double columnMajorAccess() {
        double sum = 0.0;
        for (int j = 0; j < cols; ++j) {
            for (int i = 0; i < rows; ++i) {
                sum += data[i][j];  // 连续访问同一列的元素
            }
        }
        return sum;
    }

    // 显示矩阵（只显示小矩阵）
    void display() {
        if (rows > 10 || cols > 10) {
            std::cout << "矩阵太大，只显示前5x5部分:\n";
            for (int i = 0; i < std::min(5, rows); ++i) {
                for (int j = 0; j < std::min(5, cols); ++j) {
                    std::cout << std::setw(8) << std::fixed << std::setprecision(2) << data[i][j];
                }
                std::cout << "\n";
            }
        }
        else {
            for (int i = 0; i < rows; ++i) {
                for (int j = 0; j < cols; ++j) {
                    std::cout << std::setw(8) << std::fixed << std::setprecision(2) << data[i][j];
                }
                std::cout << "\n";
            }
        }
    }

    int getRows() const { return rows; }
    int getCols() const { return cols; }
};

// 性能测试函数
void performanceTest(Matrix& matrix) {
    std::cout << "\n=== 性能测试开始 ===\n";
    std::cout << "矩阵大小: " << matrix.getRows() << " x " << matrix.getCols() << "\n";

    // 测试行优先访问
    auto start = std::chrono::high_resolution_clock::now();
    double rowSum = matrix.rowMajorAccess();
    auto end = std::chrono::high_resolution_clock::now();
    auto rowTime = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

    // 测试列优先访问
    start = std::chrono::high_resolution_clock::now();
    double colSum = matrix.columnMajorAccess();
    end = std::chrono::high_resolution_clock::now();
    auto colTime = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

    // 显示结果
    std::cout << "\n测试结果:\n";
    std::cout << "行优先访问时间: " << rowTime.count() << " 微秒\n";
    std::cout << "列优先访问时间: " << colTime.count() << " 微秒\n";
    std::cout << "行优先求和: " << std::fixed << std::setprecision(2) << rowSum << "\n";
    std::cout << "列优先求和: " << std::fixed << std::setprecision(2) << colSum << "\n";

    // 性能比较
    if (rowTime.count() < colTime.count()) {
        double speedup = static_cast<double>(colTime.count()) / rowTime.count();
        std::cout << "行优先比列优先快 " << std::fixed << std::setprecision(2) << speedup << " 倍\n";
    }
    else {
        double speedup = static_cast<double>(rowTime.count()) / colTime.count();
        std::cout << "列优先比行优先快 " << std::fixed << std::setprecision(2) << speedup << " 倍\n";
    }
}

int main() {
    std::cout << "=== 矩阵行与列访问性能测试 ===\n\n";

    // 测试1: 小矩阵
    std::cout << "测试1: 小矩阵 (100x100)\n";
    Matrix smallMatrix(100, 100);
    smallMatrix.randomInitialize();
    performanceTest(smallMatrix);

    std::cout << "\n" << std::string(50, '=') << "\n";

    // 测试2: 大矩阵
    std::cout << "测试2: 大矩阵 (1000x1000)\n";
    Matrix largeMatrix(1000, 1000);
    largeMatrix.randomInitialize();
    performanceTest(largeMatrix);

    std::cout << "\n" << std::string(50, '=') << "\n";

    // 测试3: 非方阵
    std::cout << "测试3: 非方阵 (500x800)\n";
    Matrix rectMatrix(500, 800);
    rectMatrix.randomInitialize();
    performanceTest(rectMatrix);

    std::cout << "\n=== 测试完成 ===\n";

    // 等待用户输入
    std::cout << "\n按Enter键退出...";
    std::cin.get();

    return 0;
}

//矩阵大小：100×100
//行优先访问时间：545微妙
//列优先访问时间：385微妙
//列优先比行优先块1.42倍

//矩阵大小：1000×1000
//行优先访问时间：7759微妙
//列优先访问时间：12800
//行优先比列优先快1.65倍